#include "AdministradorDeNiveles.h"
#include <iostream>
#include <fstream>
#include <sstream>
AdministradorDeNiveles::AdministradorDeNiveles() { 
}

AdministradorDeNiveles::~AdministradorDeNiveles() { }

list<string> AdministradorDeNiveles::nivelesHabilitados() { 
	list<string> l;
	string nivel, archivo, estado;
	char linea[100];
	ifstream niveles(INFO_NIVELES);
	if (!niveles.good()) {
		// Manejo de errores
		cout << "Administrador de niveles: Archivo de informacion de niveles " << INFO_NIVELES << " no encontrado" << endl;
	}

	while (niveles.getline(linea, 100, '\n')) {
		string str(linea);
		parsearLinea(str, nivel, archivo, estado);
		
		if (estado == "l") {  // Si el nivel esta liberado
			l.push_front(nivel);
		}
		
		nivel = "";
		estado = "";
		archivo = "";
	}
	
	niveles.close();
	return l;
}

void AdministradorDeNiveles::habilitarNivel(string nivel) {
	ofstream out;
	int pos = buscarPosEstadoNivel(nivel);
	
	if (pos > 0) {
		out.open(INFO_NIVELES, ios::out|ios::in|ios::ate);
		out.seekp(pos);
		out.put('l');
		out.close();
	}
}

void AdministradorDeNiveles::habilitarNivel(short nivel) {
	stringstream strNivel;
	strNivel << nivel;
	habilitarNivel(strNivel.str());
}

Nivel* AdministradorDeNiveles::instanciarNivel(string nivel, short cantidadDeJugadores) {
	Nivel* n = NULL;
	string codNivel, archivo, estado;

	string linea = getLineaNivel(nivel);
	if (linea != "") { 
		parsearLinea(linea, codNivel, archivo, estado);
			
		if (verificarArchivo(archivo)) {			
			n = new Nivel(archivo,cantidadDeJugadores);
		}
		else {
			cout << "Administrador de niveles: Archivo para nivel "<< archivo << " no encontrado" << endl;
		}
	}
	
	return n;
}

Nivel* AdministradorDeNiveles::instanciarNivel(int nivel, short cantidadDeJugadores) {
	stringstream strNivel;
	strNivel << nivel;
	return instanciarNivel(strNivel.str(), cantidadDeJugadores);
}

void AdministradorDeNiveles::parsearLinea(string linea, string &nivel, string &arch, string &estado) {
	int posPriComa = linea.find(',', 0);
	int posSegComa = linea.find(',', posPriComa + 1);
	
	if (posPriComa > 0) {
		nivel = linea.substr(0, posPriComa);
		arch = linea.substr(posPriComa + 1, posSegComa - posPriComa - 1);
		estado = linea.substr(posSegComa + 1, linea.size() - posSegComa);
	}
}

bool AdministradorDeNiveles::verificarArchivo(string archivo) {
	bool resultado = true;
	ifstream in(archivo.c_str());
	if (!in.good())
		resultado = false;
	in.close();
	return resultado;
}

bool AdministradorDeNiveles::nivelHabilitado(string nivel) {
	string arch = "";
	string estado = "";
	string linea = getLineaNivel(nivel);
	
	if (linea != "") {
		parsearLinea(linea, nivel, arch, estado);
	}
	
	return (estado == "l");
}

string AdministradorDeNiveles::getLineaNivel(string nivel) {
	ifstream niveles(INFO_NIVELES);
	char linea[100];
	string ret = "";
	bool encontrado = false;
	while (niveles.getline(linea, 100, '\n') && !encontrado) {
		string str(linea);
		int posPriComa = str.find(',', 0);
		string nivelLeido = str.substr(0, posPriComa);
		if (nivel == nivelLeido) {
			ret = str;
			encontrado = true;
		}
	}
	niveles.close();
	return ret;
}

bool AdministradorDeNiveles::nivelHabilitado(short nivel) {
	stringstream strNivel;
	strNivel << nivel;
	return nivelHabilitado(strNivel.str());
}

int AdministradorDeNiveles::buscarPosEstadoNivel(string nivel) {
	ifstream niveles(INFO_NIVELES);
	char linea[100];
	int ret = 0;
	bool encontrado = false;
	while (niveles.getline(linea, 100, '\n') && !encontrado) {
		string str(linea);
		int posPriComa = str.find(',', 0);
		string nivelLeido = str.substr(0, posPriComa);
		if (nivel == nivelLeido) {
			ret = niveles.tellg();
			ret -= 2;
			encontrado = true;
		}
	}
	niveles.close();
	return ret;
}

void AdministradorDeNiveles::agregarNivel(string codigo, string archivo, string estado) {
	ofstream out;
	string linea = getLineaNivel(codigo);
	
	if (linea == "") {
		stringstream str;
		str << codigo << "," << archivo << "," << estado;
		out.open(INFO_NIVELES, ios::app);
		out.write(str.str().c_str(), str.str().size());
		out.close();
	}
}
